package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ciei.dpagm.entity.*;
import com.ciei.dpagm.common.converter.JsonConverter;
import com.ciei.dpagm.common.enums.ErrorCodeEnum;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.util.*;
import com.ciei.dpagm.mapper.DepartmentMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class DepartmentService extends BaseService<DepartmentMapper, Department> {

	@Autowired
	private UsersService usersService;

	
	@Autowired
    private UserRoleService userRoleService;
	@Autowired
    private RoleService roleService;
	@Autowired
	private CompanyService companyService;

	@Autowired
	private AutoCodeSeedService autoCodeSeedService;


	/**
	 * 保存部门信息
	 * @param jsonObject
	 * @return
	 */
	public JSONObject addVue(JSONObject jsonObject,Integer companyId) {
		Department department = new Department();
		String departmentName = jsonObject.getString("name");
		Integer parentId;
		JSONObject json = new JSONObject();
		List<Department> dList = null;
		if(jsonObject.getInteger("parentId")!=null){
			parentId = jsonObject.getInteger("parentId");
			Department depar = findById(parentId);
			if (depar != null) {
				if(departmentName.equals(depar.getDepartmentName())) {
					json = JsonUtil.getFail("该部门名称跟上级部门名称冲突,保存失败!");
					return json;
				}
			}
			department.setParentDepartmentId(parentId);
		}else{
			//如果是null,说明父节点为公司，添加公司的一级部门子节点，父节点应该为0
			department.setParentDepartmentId(0);
			department.setLevelCode("0");
			parentId = 0;
		}
		List<Department> list = findByProperties(new String[]{"departmentName","companyId","isDelete"},new Object[]{departmentName,companyId, 0});
		if(list.size()>0 && list != null) {
			json = JsonUtil.getFail("该部门名字已经存在,保存失败!");
			return json;
		}
		String departmentCode = jsonObject.getString("departmentCode");
		LambdaQueryWrapper<Department> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(Department::getDepartmentCode,departmentCode)
				.eq(Department::getCompanyId,companyId);
		int sameDepartmentCodeCount = count(lambdaQueryWrapper);
		if(sameDepartmentCodeCount > 0){
			return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"该部门编号已经存在,保存失败!");
		}
		department.setCompanyId(companyId);
		department.setDepartmentName(departmentName);
		department.setDepartmentCode(departmentCode);

		/**
		 * 手工添加部门的ID
		 */
		department.setDepartmentId(autoCodeSeedService.GetNewID("DepartmentID", 1));
		if("0".equals(parentId)){
			department.setLevelCode(String.valueOf(department.getDepartmentId()));
		}else{
			department.setLevelCode(parentId+"!"+department.getDepartmentId());

		}
		save(department);
		json = JsonUtil.getSuccess("保存成功!");
		return json;
	}
	public JSONObject deleteVue(JSONObject jsonObject) {
		JSONObject json;
		//当删除的部门有子部门时，子部门也遍历删除
		if(jsonObject.getInteger("departmentId")!=null) {
			Integer departmentId = jsonObject.getInteger("departmentId");
			Department department = findById(departmentId);
			List<Department> departmentList = new ArrayList<>();
			List<Department> allDepartment = null;
			if (departmentId != null) {
				Set<Integer> sonIdSet = new HashSet<>();
				allDepartment = getBaseMapper().listSameCompanyDepartments(departmentId);
				loadChildrenDepartmentIds(allDepartment, departmentId, sonIdSet);
				departmentList = findListByIds(sonIdSet);
			}

			if(department != null) {
				if(departmentList != null && departmentList.size()>0) {
					for(Department departmentSum:departmentList){
						departmentSum.setIsDelete(1);
					}
					updateBatchById(departmentList);
				}
				json = JsonUtil.getSuccess("删除成功!");
			}else{
				json = JsonUtil.getFail("删除失败!");
			}
		}else{
			json = JsonUtil.getFail("departmentId不能为空,删除失败!");

		}
		return json;
	}

	public JSONObject updateCompanyNameVue(JSONObject jsonObject) {
		JSONObject json;
		if(jsonObject.getString("companyName")==null || jsonObject.getString("companyName")=="" || jsonObject.getInteger("companyId") ==null){
			json = JsonUtil.getSuccess("公司名称或编号不能为空,更新失败!");
		}else{
			String companyName=jsonObject.getString("companyName");
			Company company=new Company();
			String[] propertyNames = {"companyName","isDelete"};
			String[] values = {companyName,"0"};
			List<Company> coms=companyService.findByProperties(propertyNames, values);
			if(coms.size()>0) {
				json = JsonUtil.getFail("公司名称已存在,更新失败！");
			}else{
				company.setCompanyId(jsonObject.getInteger("companyId"));
				company.setCompanyName(companyName);
				companyService.updateById(company);
				json = JsonUtil.getSuccess("更新成功!");
			}
		}
		return json;
	}

	/**
	 * 更新
	 * @param data
	 * @return
	 */
	public JSONObject update(JSONObject data) {
		JsonConverter<Department> jsonConverter = new JsonConverter<>();
		Department department = jsonConverter.convert(data, Department.class);
		if(StringUtils.isBlank(department.getDepartmentName())){
			return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"部门名称不能为空，请检查");
		}
		if(department.getDepartmentId() == null){
			return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"部门编号不能为空，请检查");
		}
		Department oldDepartment = findById(department.getDepartmentId());
		LambdaQueryWrapper<Department> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(Department::getDepartmentName,department.getDepartmentName())
				.eq(Department::getCompanyId,oldDepartment.getCompanyId())
				.ne(Department::getDepartmentId,department.getDepartmentId());
		int sameDepartmentNameCount = count(lambdaQueryWrapper);
		if(sameDepartmentNameCount > 0){
			return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"该部门名称已存在");
		}
		if(StringUtils.isNotBlank(department.getDepartmentCode())){
			LambdaQueryWrapper<Department> judgeCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
			judgeCodeLambdaQueryWrapper.eq(Department::getDepartmentCode,department.getDepartmentCode())
					.eq(Department::getCompanyId,oldDepartment.getCompanyId())
					.ne(Department::getDepartmentId,department.getDepartmentId());
			int sameDepartmentCodeCount = count(judgeCodeLambdaQueryWrapper);
			if(sameDepartmentCodeCount > 0){
				return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"该部门编号已存在");
			}
		}
		updateById(department);
		return JsonUtil.getSuccess("更新成功!");

	}

	public String getDepartmentName(Integer departmentId){
		Department d=findById(departmentId);
		if(d!=null){
			return d.getDepartmentName();
		}else{
			return  null;
		}
	}
	public JSONObject loadTreeVue(Integer companyId){
		List<Department> lists = findByProperties(new String[]{"isDelete","companyId"}, new Object[]{"0", companyId});
		JSONObject json = new JSONObject();
		Map<String, Object> oneMap = new HashMap<String, Object>();
		oneMap.put("id",companyId);
		oneMap.put("label",companyService.getCompanyName(companyId));
		List<TreeNode> treeNodes= TreeUtils.buildTree(lists
				, Department::getDepartmentId
				, Department::getParentDepartmentId
				, Department::getDepartmentName);
		oneMap.put("children",treeNodes);
		oneMap.put("company",true);
		json.fluentPut(APP.DATA, oneMap);
		return json;
	}
	public JSONObject loadDepartmentTree(Integer companyId){
		List<Department> lists = findByProperties(new String[]{"isDelete","companyId"}, new Object[]{"0", companyId});
		JSONObject json = new JSONObject();
		Map<String, Object> oneMap = new HashMap<String, Object>();
		oneMap.put("id",companyId);
		oneMap.put("label",companyService.getCompanyName(companyId));
		List<TreeNode> treeNodes=TreeUtils.buildTree(lists
				, Department::getDepartmentId
				, Department::getParentDepartmentId
				, Department::getDepartmentName);
		json.fluentPut(APP.DATA, treeNodes);
		return json;
	}

	/**
	 * 根据部门ID获取所有下级部门的ID
	 * @param allDepartments	部门范围全集
	 * @param departmentId		部门ID
	 * @param idSet				筛选出的部门ID，包含部门本身及其所有下级部门的ID
	 */
    public void loadChildrenDepartmentIds(List<Department> allDepartments, Integer departmentId, Set<Integer> idSet) {
        Queue<Integer> departmentIdQueue = new LinkedList<>();
        departmentIdQueue.add(departmentId);
        while (!departmentIdQueue.isEmpty()) {
        	Integer id = departmentIdQueue.poll();
        	idSet.add(id);
        	List<Integer> childrenIds = allDepartments.stream().filter(d -> id.equals(d.getParentDepartmentId()))
					.map(Department::getDepartmentId).filter(Objects::nonNull).collect(Collectors.toList());
        	departmentIdQueue.addAll(childrenIds);
		}
    }

	/**
	 * 根据部门读取用户数据
	 * @param param		分页查询条件
	 * @return			用户表格数据
	 */
	public JSONObject loadUserByDepartment(PageParam param) {
		JSONObject json;
		json = JsonUtil.getSuccess("Ok");
		Integer departmentId;
		JSONArray jarr = new JSONArray();
		int currentPage = param.getCurrentPage();
		int pageSize = param.getPageSize();
		String[] inFields = new String[]{"departmentId"};
		String[] likeFields = new String[]{"userName"};
		String[] equalFields = new String[]{"isDelete", "locked", "companyId"};
		Map<String, Object> params = param.getParams();
		Map<String, Object> sortFields = param.getSort();
		params.put("isDelete", 0);
		params.put("locked", 0);

		List<Department> allDepartment = null;
		if (param.params.containsKey("departmentId")) {
			departmentId = (Integer) param.params.get("departmentId");
			if (departmentId != null) {
				Set<Integer> sonIdSet = new HashSet<>();
				allDepartment = getBaseMapper().listSameCompanyDepartments(departmentId);
				loadChildrenDepartmentIds(allDepartment, departmentId, sonIdSet);
				params.put("departmentId", new ArrayList<>(sonIdSet));
			}
		}
		if (allDepartment == null) {
			allDepartment = findByProperty("isDelete", 0);
		}
		IPage<Users> page = usersService.findPageVue(currentPage, pageSize, params, likeFields, equalFields, sortFields, inFields);
		List<Users> userList = page.getRecords();
		if (userList != null && userList.size() > 0) {
			LambdaQueryWrapper<UserRole> userRoleQueryWrapper = new LambdaQueryWrapper<>();
			userRoleQueryWrapper.in(UserRole::getUserId, userList.stream().map(Users::getUserId).collect(Collectors.toList()));
			List<UserRole> userRoleList = userRoleService.list(userRoleQueryWrapper);
			List<Role> roleList = roleService.findListByIds(userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toSet()));
			for (Users user : userList) {
				Map<String, Object> data = new HashMap<>(16);
				data.put("id", user.getUserId());
				data.put("userId", user.getUserId());
				data.put("loginName", user.getLoginName());
				data.put("userName", user.getUserName());
				data.put("email", user.getEmail());
				data.put("mobilTel", user.getMobileTel());
				data.put("telephone", user.getTelephone());
				data.put("address", user.getAddress());
				//获取用户的所有角色
				List<String> roleNames = roleList.stream().filter(role ->
						userRoleList.stream().filter(ur -> user.getUserId().equals(ur.getUserId())).map(UserRole::getRoleId).collect(Collectors.toSet())
								.contains(role.getRoleId())
				).map(Role::getRoleName).collect(Collectors.toList());
				data.put("roleNames", roleNames);
				Department department = allDepartment.stream().filter(d -> d.getDepartmentId().equals(user.getDepartmentId())).findFirst().orElse(null);
				data.put("departmentName", department == null ? "" : department.getDepartmentName());
				jarr.add(data);
			}
		}
		json.put(APP.DATA, jarr);
		json.put(APP.TOTAL_COUNT, page.getTotal());
		json.put(APP.CURRENT_PAGE, page.getCurrent());
		return json;
	}

	/**
	 * 获取编码不为空部门列表
	 * @return
	 */
	public List<Department> getCodeNotNullList(Integer companyId){
		LambdaQueryWrapper<Department> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.isNotNull(Department::getDepartmentCode)
				.eq(Department::getCompanyId,companyId);
		return list(lambdaQueryWrapper);
	}

	/**
	 * 初始化
	 * @param departmentId
	 * @return
	 */
	public JSONObject init(Integer departmentId){
		Department department = findById(departmentId);
		if(department == null){
			return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的部门数据，请检查传入的id是否有误");
		}
		JSONObject data = new JSONObject();
		data.fluentPut("departmentId",department.getDepartmentId())
				.fluentPut("departmentName",department.getDepartmentName() == null ? "" : department.getDepartmentName())
				.fluentPut("departmentCode",department.getDepartmentCode() == null ? "" : department.getDepartmentCode());
		return JsonUtil.getSuccess("").fluentPut(APP.DATA,data);
	}
}